package token

import (
	"fmt"

	"github.com/golang-jwt/jwt/v4"
)

type Custom struct {
	ID       uint
	NickName string
	RoleID   uint
}

type CustomClaims struct {
	Custom
	jwt.RegisteredClaims
}

// JWTTokenVerifier verifies jwt access tokens.
type JWTTokenVerifier struct {
	SigningKey []byte
}

// Verify verifies a token and returns custom claims.
func (v *JWTTokenVerifier) Verify(token string) (Custom, error) {
	clm := &CustomClaims{}
	t, err := jwt.ParseWithClaims(token, clm,
		func(*jwt.Token) (interface{}, error) {
			return v.SigningKey, nil
		},
	)
	if err != nil {
		return clm.Custom, fmt.Errorf("cannot parse token: %v", err)
	}

	if !t.Valid {
		return clm.Custom, fmt.Errorf("token not valid")
	}

	cls, ok := t.Claims.(*CustomClaims)
	if !ok {
		return clm.Custom, fmt.Errorf("token claim is not Custom")
	}

	if err := cls.Valid(); err != nil {
		return clm.Custom, fmt.Errorf("claim not valid: %v", err)
	}

	return cls.Custom, nil
}
